package top.boycharse.ftp.server.common;


import java.io.*;

import static top.boycharse.ftp.server.common.Response.*;

public class CommandInterpreter {

    private final static String USER_COMMAND = "user";

    private final static String USER_PASS = "pass";

    private final static String RETR = "retr";

    private final static String NLIST = "nlist";

    private final static String PWD = "pwd";

    private final static String CWD = "cwd";

    private final static String CDUP = "cdup";

    private final static String STOR = "stor";

    private final static String APPE = "appe";

    private String pwd;

    private DataOutputStream output;

    private boolean isLogin;

    private String userName;

    private String password;

    private String IP;

    private int port;

    private DataDTP dtp;

    public CommandInterpreter(OutputStream output,String IP, int port) {
        this.output = new DataOutputStream(output);
        this.IP = IP;
        this.port = port;
        // 初始化当前路径为项目路径
        File file = new File("");
        pwd = file.getAbsolutePath();
        this.dtp = new DataDTP(IP, port);
        write(CODE_220);
    }

    /**
     * 解析命令并调用相应的函数
     * @param command
     */
    public void interpreter(String command) {
        int index = command.indexOf(' ');
        if (index != -1) {
            String commandName = command.substring(0, command.indexOf(' ')).toLowerCase();
            switch (commandName) {
                case USER_COMMAND:
                    user(command);
                    break;
                case USER_PASS:
                    pass(command);
                    break;
                case RETR:
                    retr(command);
                    break;
                case NLIST:
                    nlist(command);
                    break;
                case CWD:
                    cwd(command);
                    break;
                case STOR:
                    stor(command);
                    break;
                case APPE:
                    appe(command);
                    break;
                default:
                    error();
            }
        }else {
            switch (command) {
                case PWD:
                    pwd(command);
                    break;
                case NLIST:
                    nlist(command);
                    break;
                case CDUP:
                    cdup(command);
                    break;
                default:
                    write(CODE_500);
            }
        }
    }

    private void appe(String command) {
        if (!isLogin) {
            write(CODE_550);
            return;
        }

        String path = command.substring(command.indexOf(' ') + 1);
        write("150 " + path + "\n");
        File file = new File(path);
        String filepath = pwd + "/" + file.getName();
        dtp.append(filepath, new DataDTP.UpLoadListener() {
            @Override
            public void onSuccess() {
                write("200 file append success\n");
            }

            @Override
            public void onException() {

            }
        });
    }

    /**
     * 将文件上传到当前工作区
     * @param command
     */
    private void stor(String command) {
        if (!isLogin) {
            write(CODE_550);
            return;
        }

        String path = command.substring(command.indexOf(' ') + 1);
        write("150 " + path + "\n");
        File file = new File(path);
        String filepath = pwd + "/" + file.getName();
        dtp.upload(filepath, new DataDTP.UpLoadListener() {
            @Override
            public void onSuccess() {
                write("200 file upload success\n");
            }

            @Override
            public void onException() {

            }
        });
    }

    private void cdup(String command) {
        if (!isLogin) {
            write(CODE_550);
            return;
        }

        if (pwd.equals("/")) {
            write("550 root is not parent\n");
        }else {
            File file = new File(pwd);
            pwd = file.getParent();
            write("200 directory is change to " + pwd + "\n");
        }
    }

    private void cwd(String command) {
        if (!isLogin) {
            write(CODE_550);
            return;
        }

        String path = command.substring(command.indexOf(' ') + 1);
        if (path.charAt(0) == '/') {
            // 绝对路径
        }else {
            // 相对路径
            path = pwd + "/" + path;
        }
        File file = new File(path);
        if (file.exists()) {
            if (!file.isDirectory()) {
                write("500 it is not directory\n");
            }else {
                pwd = path;
                write("200 directory is change to " + pwd + "\n");
            }
        }else {
            write("550 directory is not exist\n");
        }
    }

    private void nlist(String command) {
        if (!isLogin) {
            write(CODE_550);
            return;
        }

        int index = command.indexOf(' ');
        write(CODE_212);
        if (index != -1) {
            String path = command.substring(index + 1);
            if (path.charAt(0) == '/') {
                // 绝对路径
            }else {
                // 相对路径
                path = pwd + "/" + path;
            }
            String[] fileNames = getFileNames(path);
            dtp.returnFileNames(fileNames);
        }else {
            // 当前工作目录的文件名
            String[] fileNames = getFileNames(pwd);
            dtp.returnFileNames(fileNames);
        }
    }

    private String[] getFileNames(String dir) {

        File file = new File(dir);
        String[] fileNames = file.list();
        return fileNames;
    }

    private void pwd(String command) {
        if (!isLogin) {
            write(CODE_550);
            return;
        }

        write(CODE_APPEND_200 + ",current dir is " + "\"" + pwd + "\"" + "\n");
    }

    /**
     * USER 命令
     * @param command
     */
    private void user(String command) {
        String userName = command.substring(command.indexOf(' ') + 1);
        if (UserInfo.getInstance().isExitUser(userName)) {
            write(CODE_331);
            this.userName = userName;
        }else {
            write(CODE_530);
        }
    }

    private void pass(String command) {
        String pass = command.substring(command.indexOf(' ') + 1);
        if (userName == null) {
            write(CODE_503);
            return;
        }
        if (UserInfo.getInstance().isPassConfig(userName,pass)) {
            isLogin = true;
            password = pass;
            write(CODE_230);
        }else {
            write(CODE_530);
        }
    }

    private void retr(String command) {
        if (!isLogin) {
            write(CODE_550);
            return;
        }
        String pathname = command.substring(command.indexOf(' ') + 1);
        if (pathname.charAt(0) == '/') {
            // 绝对路径
        }else {
            // 相对路径
            pathname = pwd + "/" + pathname;
        }
        File file = new File(pathname);
        if (file.exists() && file.isFile()) {
            write(CODE_150 + ' ' + file.getName() + '\n');
            dtp.waitDownload(pathname, new DataDTP.DownLoadListener() {
                @Override
                public void open() {
                    write(CODE_125);
                }

                @Override
                public void onSuccess() {
                    write(CODE_250);
                }

                @Override
                public void onException() {

                }
            });
        }else {
            write(CODE_450);
        }
    }

    private void error() {
        write(CODE_502);
    }

    private void write(String info) {
        try{
            output.writeBytes(info);
            output.flush();
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}
